{
  "cells": [
    {
      "cell_type": "code",
      "source": [
        "%load_ext autoreload\n",
        "%autoreload 2"
      ],
      "outputs": [],
      "execution_count": null,
      "metadata": {
        "collapsed": true,
        "slideshow": {
          "slide_type": "skip"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "%config InlineBackend.figure_format = 'retina'\n",
        "%matplotlib inline\n",
        "\n",
        "# import modules\n",
        "import numpy as np\n",
        "import pandas as pd\n",
        "\n",
        "# settings (pandas)\n",
        "pd.set_option('notebook_repr_html', True)\n",
        "pd.set_option('expand_frame_repr', False)\n",
        "\n",
        "import datetime\n",
        "import time\n",
        "from pprint import pprint as pretty_print\n"
      ],
      "outputs": [],
      "execution_count": 21,
      "metadata": {
        "collapsed": true,
        "slideshow": {
          "slide_type": "skip"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "<img style=\"max-width:100px!important;border-radius:50%;margin:0\" src=\"http://aroussi.com/assets/img/ran.jpg\">\n",
        "\n",
        "# Live Algorithmic Trading with Python\n",
        "\n",
        "---\n",
        "\n",
        "### How To Make Your Trading Strategies Work On Live Markets\n",
        "\n",
        "<br>\n",
        "\n",
        "&copy; Ran Aroussi<br>\n",
        "[@aroussi](http://twitter.com/aroussi) | [aroussi.com](http://aroussi.com) | [github.com/ranaroussi](https://github.com/ranaroussi)\n",
        "\n\n",
        "<img style=\"float:left; max-width:120px!important;margin:20px 0 0\" src=\"https://futures.io/images/logo-black.png\">\n",
        "<br clear=\"all\"><br><small>August, 2017</small>"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "slide"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Agenda\n",
        "\n",
        "- Working with the 3 types of market data:\n",
        "    - EOD market data\n",
        "    - Timed market data snapshopts\n",
        "    - Live streaming data\n",
        "- How to execute and monitor trades in live markets\n",
        "- Live examples using Interactive Brokers and Oanda FX"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "slide"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "---"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "skip"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Working with Market Data"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "slide"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Working with Market Data\n",
        "\n",
        "- EOD market data (for daily strategies)\n",
        "- Timed market data snapshopts (usually for intraday strategies)\n",
        "- Live (or paper) streaming data (for anything, really 😁)"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "## EOD Market Data Sources\n",
        "\n",
        "(live example to follow)\n",
        "- Historical market data providers\n",
        "- Live market data feed providers\n",
        "- Your broker"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "slide"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "## EOD Market Data Sources\n",
        "\n",
        "- Historical market data providers\n",
        "    - Quandl\n",
        "    - Yahoo! Finance\n",
        "    - EODData.com\n",
        "    - Tick data providers (QuantQuote.com, TickData.com, ...) \n",
        "- Live market data feed providers\n",
        "    - IQFeed\n",
        "    - Rithmic\n",
        "    - CQG\n",
        "    - ...\n",
        "- Your broker"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Downloading EOD Market Data"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "slide"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Quandl Example: EOD Stocks"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "import quandl\n",
        "# quandl.ApiConfig.api_key = \"YOUR_KEY_HERE\"\n",
        "\n",
        "df = quandl.get('WIKI/AAPL')\n",
        "df.tail()"
      ],
      "outputs": [
        {
          "output_type": "execute_result",
          "execution_count": 3,
          "data": {
            "text/html": [
              "<div>\n",
              "<style>\n",
              "    .dataframe thead tr:only-child th {\n",
              "        text-align: right;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: left;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>Open</th>\n",
              "      <th>High</th>\n",
              "      <th>Low</th>\n",
              "      <th>Close</th>\n",
              "      <th>Volume</th>\n",
              "      <th>Ex-Dividend</th>\n",
              "      <th>Split Ratio</th>\n",
              "      <th>Adj. Open</th>\n",
              "      <th>Adj. High</th>\n",
              "      <th>Adj. Low</th>\n",
              "      <th>Adj. Close</th>\n",
              "      <th>Adj. Volume</th>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>Date</th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>2017-08-17</th>\n",
              "      <td>160.52</td>\n",
              "      <td>160.71</td>\n",
              "      <td>157.8400</td>\n",
              "      <td>157.87</td>\n",
              "      <td>26925694.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>160.52</td>\n",
              "      <td>160.71</td>\n",
              "      <td>157.8400</td>\n",
              "      <td>157.87</td>\n",
              "      <td>26925694.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2017-08-18</th>\n",
              "      <td>157.86</td>\n",
              "      <td>159.50</td>\n",
              "      <td>156.7200</td>\n",
              "      <td>157.50</td>\n",
              "      <td>27012525.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>157.86</td>\n",
              "      <td>159.50</td>\n",
              "      <td>156.7200</td>\n",
              "      <td>157.50</td>\n",
              "      <td>27012525.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2017-08-21</th>\n",
              "      <td>157.50</td>\n",
              "      <td>157.89</td>\n",
              "      <td>155.1101</td>\n",
              "      <td>157.21</td>\n",
              "      <td>26145653.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>157.50</td>\n",
              "      <td>157.89</td>\n",
              "      <td>155.1101</td>\n",
              "      <td>157.21</td>\n",
              "      <td>26145653.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2017-08-22</th>\n",
              "      <td>158.23</td>\n",
              "      <td>160.00</td>\n",
              "      <td>158.0200</td>\n",
              "      <td>159.78</td>\n",
              "      <td>21297812.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>158.23</td>\n",
              "      <td>160.00</td>\n",
              "      <td>158.0200</td>\n",
              "      <td>159.78</td>\n",
              "      <td>21297812.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2017-08-23</th>\n",
              "      <td>159.07</td>\n",
              "      <td>160.47</td>\n",
              "      <td>158.8800</td>\n",
              "      <td>159.98</td>\n",
              "      <td>19198189.0</td>\n",
              "      <td>0.0</td>\n",
              "      <td>1.0</td>\n",
              "      <td>159.07</td>\n",
              "      <td>160.47</td>\n",
              "      <td>158.8800</td>\n",
              "      <td>159.98</td>\n",
              "      <td>19198189.0</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ],
            "text/plain": [
              "              Open    High       Low   Close      Volume  Ex-Dividend  Split Ratio  Adj. Open  Adj. High  Adj. Low  Adj. Close  Adj. Volume\n",
              "Date                                                                                                                                       \n",
              "2017-08-17  160.52  160.71  157.8400  157.87  26925694.0          0.0          1.0     160.52     160.71  157.8400      157.87   26925694.0\n",
              "2017-08-18  157.86  159.50  156.7200  157.50  27012525.0          0.0          1.0     157.86     159.50  156.7200      157.50   27012525.0\n",
              "2017-08-21  157.50  157.89  155.1101  157.21  26145653.0          0.0          1.0     157.50     157.89  155.1101      157.21   26145653.0\n",
              "2017-08-22  158.23  160.00  158.0200  159.78  21297812.0          0.0          1.0     158.23     160.00  158.0200      159.78   21297812.0\n",
              "2017-08-23  159.07  160.47  158.8800  159.98  19198189.0          0.0          1.0     159.07     160.47  158.8800      159.98   19198189.0"
            ]
          },
          "metadata": {}
        }
      ],
      "execution_count": 3,
      "metadata": {}
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Quandl Example: Continuous Futures Contract"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "df = quandl.get('CHRIS/CME_CL1')\n",
        "df.tail()\n",
        "\n",
        "# see more python methods @ quandl.com/tools/python\n",
        "\n",
        "# Useful databases:\n",
        "# - https://www.quandl.com/data/WIKI-Wiki-EOD-Stock-Prices\n",
        "# - https://www.quandl.com/data/CHRIS-Wiki-Continuous-Futures"
      ],
      "outputs": [
        {
          "output_type": "execute_result",
          "execution_count": 4,
          "data": {
            "text/html": [
              "<div>\n",
              "<style>\n",
              "    .dataframe thead tr:only-child th {\n",
              "        text-align: right;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: left;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>Open</th>\n",
              "      <th>High</th>\n",
              "      <th>Low</th>\n",
              "      <th>Last</th>\n",
              "      <th>Change</th>\n",
              "      <th>Settle</th>\n",
              "      <th>Volume</th>\n",
              "      <th>Previous Day Open Interest</th>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>Date</th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>2017-08-17</th>\n",
              "      <td>46.80</td>\n",
              "      <td>47.19</td>\n",
              "      <td>46.46</td>\n",
              "      <td>46.93</td>\n",
              "      <td>0.31</td>\n",
              "      <td>47.09</td>\n",
              "      <td>596093.0</td>\n",
              "      <td>161590.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2017-08-18</th>\n",
              "      <td>46.93</td>\n",
              "      <td>48.74</td>\n",
              "      <td>46.78</td>\n",
              "      <td>48.73</td>\n",
              "      <td>1.42</td>\n",
              "      <td>48.51</td>\n",
              "      <td>247019.0</td>\n",
              "      <td>96943.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2017-08-21</th>\n",
              "      <td>48.72</td>\n",
              "      <td>48.75</td>\n",
              "      <td>47.03</td>\n",
              "      <td>47.40</td>\n",
              "      <td>1.14</td>\n",
              "      <td>47.37</td>\n",
              "      <td>124355.0</td>\n",
              "      <td>62446.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2017-08-22</th>\n",
              "      <td>47.45</td>\n",
              "      <td>48.03</td>\n",
              "      <td>47.20</td>\n",
              "      <td>47.65</td>\n",
              "      <td>0.27</td>\n",
              "      <td>47.64</td>\n",
              "      <td>28373.0</td>\n",
              "      <td>25636.0</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2017-08-23</th>\n",
              "      <td>47.64</td>\n",
              "      <td>48.50</td>\n",
              "      <td>47.53</td>\n",
              "      <td>48.37</td>\n",
              "      <td>0.58</td>\n",
              "      <td>48.41</td>\n",
              "      <td>700754.0</td>\n",
              "      <td>522164.0</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ],
            "text/plain": [
              "             Open   High    Low   Last  Change  Settle    Volume  Previous Day Open Interest\n",
              "Date                                                                                        \n",
              "2017-08-17  46.80  47.19  46.46  46.93    0.31   47.09  596093.0                    161590.0\n",
              "2017-08-18  46.93  48.74  46.78  48.73    1.42   48.51  247019.0                     96943.0\n",
              "2017-08-21  48.72  48.75  47.03  47.40    1.14   47.37  124355.0                     62446.0\n",
              "2017-08-22  47.45  48.03  47.20  47.65    0.27   47.64   28373.0                     25636.0\n",
              "2017-08-23  47.64  48.50  47.53  48.37    0.58   48.41  700754.0                    522164.0"
            ]
          },
          "metadata": {}
        }
      ],
      "execution_count": 4,
      "metadata": {
        "slideshow": {
          "slide_type": "-"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Yahoo! Finance Example\n",
        "\n(Sadly, their service became very unreliable in terms of availability)"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "import fix_yahoo_finance as yf\n",
        "\n",
        "df = yf.get_data_yahoo(\"AAPL\", start=\"2010-01-01\")\n",
        "df.tail()"
      ],
      "outputs": [
        {
          "output_type": "execute_result",
          "execution_count": 5,
          "data": {
            "text/html": [
              "<div>\n",
              "<style>\n",
              "    .dataframe thead tr:only-child th {\n",
              "        text-align: right;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: left;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>Open</th>\n",
              "      <th>High</th>\n",
              "      <th>Low</th>\n",
              "      <th>Close</th>\n",
              "      <th>Adj Close</th>\n",
              "      <th>Volume</th>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>Date</th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>2017-08-18</th>\n",
              "      <td>157.860001</td>\n",
              "      <td>159.500000</td>\n",
              "      <td>156.720001</td>\n",
              "      <td>157.500000</td>\n",
              "      <td>157.500000</td>\n",
              "      <td>27428100</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2017-08-21</th>\n",
              "      <td>157.500000</td>\n",
              "      <td>157.889999</td>\n",
              "      <td>155.110001</td>\n",
              "      <td>157.210007</td>\n",
              "      <td>157.210007</td>\n",
              "      <td>26368500</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2017-08-22</th>\n",
              "      <td>158.229996</td>\n",
              "      <td>160.000000</td>\n",
              "      <td>158.020004</td>\n",
              "      <td>159.779999</td>\n",
              "      <td>159.779999</td>\n",
              "      <td>21604600</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2017-08-23</th>\n",
              "      <td>159.070007</td>\n",
              "      <td>160.470001</td>\n",
              "      <td>158.880005</td>\n",
              "      <td>159.979996</td>\n",
              "      <td>159.979996</td>\n",
              "      <td>19284400</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2017-08-24</th>\n",
              "      <td>160.429993</td>\n",
              "      <td>160.740005</td>\n",
              "      <td>158.550003</td>\n",
              "      <td>159.039993</td>\n",
              "      <td>159.039993</td>\n",
              "      <td>9437854</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ],
            "text/plain": [
              "                  Open        High         Low       Close   Adj Close    Volume\n",
              "Date                                                                            \n",
              "2017-08-18  157.860001  159.500000  156.720001  157.500000  157.500000  27428100\n",
              "2017-08-21  157.500000  157.889999  155.110001  157.210007  157.210007  26368500\n",
              "2017-08-22  158.229996  160.000000  158.020004  159.779999  159.779999  21604600\n",
              "2017-08-23  159.070007  160.470001  158.880005  159.979996  159.979996  19284400\n",
              "2017-08-24  160.429993  160.740005  158.550003  159.039993  159.039993   9437854"
            ]
          },
          "metadata": {}
        }
      ],
      "execution_count": 5,
      "metadata": {}
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Reading CSV Time-Series Files"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# read csv from eoddata.com\n",
        "df = pd.read_csv('./AAPL_20170102_20170823.csv')\n",
        "df.tail()"
      ],
      "outputs": [
        {
          "output_type": "execute_result",
          "execution_count": 6,
          "data": {
            "text/html": [
              "<div>\n",
              "<style>\n",
              "    .dataframe thead tr:only-child th {\n",
              "        text-align: right;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: left;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>Symbol</th>\n",
              "      <th>Date</th>\n",
              "      <th>Open</th>\n",
              "      <th>High</th>\n",
              "      <th>Low</th>\n",
              "      <th>Close</th>\n",
              "      <th>Volume</th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>163</th>\n",
              "      <td>AAPL</td>\n",
              "      <td>17-Aug-2017</td>\n",
              "      <td>160.52</td>\n",
              "      <td>160.71</td>\n",
              "      <td>157.84</td>\n",
              "      <td>157.86</td>\n",
              "      <td>27940500</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>164</th>\n",
              "      <td>AAPL</td>\n",
              "      <td>18-Aug-2017</td>\n",
              "      <td>157.86</td>\n",
              "      <td>159.50</td>\n",
              "      <td>156.72</td>\n",
              "      <td>157.50</td>\n",
              "      <td>27428000</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>165</th>\n",
              "      <td>AAPL</td>\n",
              "      <td>21-Aug-2017</td>\n",
              "      <td>157.50</td>\n",
              "      <td>157.89</td>\n",
              "      <td>155.11</td>\n",
              "      <td>157.21</td>\n",
              "      <td>26368500</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>166</th>\n",
              "      <td>AAPL</td>\n",
              "      <td>22-Aug-2017</td>\n",
              "      <td>158.23</td>\n",
              "      <td>160.00</td>\n",
              "      <td>158.02</td>\n",
              "      <td>159.78</td>\n",
              "      <td>21604500</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>167</th>\n",
              "      <td>AAPL</td>\n",
              "      <td>23-Aug-2017</td>\n",
              "      <td>159.07</td>\n",
              "      <td>160.47</td>\n",
              "      <td>158.88</td>\n",
              "      <td>159.98</td>\n",
              "      <td>19399000</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ],
            "text/plain": [
              "    Symbol         Date    Open    High     Low   Close    Volume\n",
              "163   AAPL  17-Aug-2017  160.52  160.71  157.84  157.86  27940500\n",
              "164   AAPL  18-Aug-2017  157.86  159.50  156.72  157.50  27428000\n",
              "165   AAPL  21-Aug-2017  157.50  157.89  155.11  157.21  26368500\n",
              "166   AAPL  22-Aug-2017  158.23  160.00  158.02  159.78  21604500\n",
              "167   AAPL  23-Aug-2017  159.07  160.47  158.88  159.98  19399000"
            ]
          },
          "metadata": {}
        }
      ],
      "execution_count": 6,
      "metadata": {}
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Reading CSV Time-Series Files"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# parse date column and set as index while reading\n",
        "df = pd.read_csv('./AAPL_20170102_20170823.csv', \n",
        "                 parse_dates=['Date'], index_col=['Date'])\n",
        "df.tail()"
      ],
      "outputs": [
        {
          "output_type": "execute_result",
          "execution_count": 7,
          "data": {
            "text/html": [
              "<div>\n",
              "<style>\n",
              "    .dataframe thead tr:only-child th {\n",
              "        text-align: right;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: left;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>Symbol</th>\n",
              "      <th>Open</th>\n",
              "      <th>High</th>\n",
              "      <th>Low</th>\n",
              "      <th>Close</th>\n",
              "      <th>Volume</th>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>Date</th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>2017-08-17</th>\n",
              "      <td>AAPL</td>\n",
              "      <td>160.52</td>\n",
              "      <td>160.71</td>\n",
              "      <td>157.84</td>\n",
              "      <td>157.86</td>\n",
              "      <td>27940500</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2017-08-18</th>\n",
              "      <td>AAPL</td>\n",
              "      <td>157.86</td>\n",
              "      <td>159.50</td>\n",
              "      <td>156.72</td>\n",
              "      <td>157.50</td>\n",
              "      <td>27428000</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2017-08-21</th>\n",
              "      <td>AAPL</td>\n",
              "      <td>157.50</td>\n",
              "      <td>157.89</td>\n",
              "      <td>155.11</td>\n",
              "      <td>157.21</td>\n",
              "      <td>26368500</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2017-08-22</th>\n",
              "      <td>AAPL</td>\n",
              "      <td>158.23</td>\n",
              "      <td>160.00</td>\n",
              "      <td>158.02</td>\n",
              "      <td>159.78</td>\n",
              "      <td>21604500</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2017-08-23</th>\n",
              "      <td>AAPL</td>\n",
              "      <td>159.07</td>\n",
              "      <td>160.47</td>\n",
              "      <td>158.88</td>\n",
              "      <td>159.98</td>\n",
              "      <td>19399000</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ],
            "text/plain": [
              "           Symbol    Open    High     Low   Close    Volume\n",
              "Date                                                       \n",
              "2017-08-17   AAPL  160.52  160.71  157.84  157.86  27940500\n",
              "2017-08-18   AAPL  157.86  159.50  156.72  157.50  27428000\n",
              "2017-08-21   AAPL  157.50  157.89  155.11  157.21  26368500\n",
              "2017-08-22   AAPL  158.23  160.00  158.02  159.78  21604500\n",
              "2017-08-23   AAPL  159.07  160.47  158.88  159.98  19399000"
            ]
          },
          "metadata": {}
        }
      ],
      "execution_count": 7,
      "metadata": {}
    },
    {
      "cell_type": "markdown",
      "source": [
        "---"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "skip"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Downloading Data from Oanda"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "slide"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Oanda Example (using REST API)"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "api_token, account_id = open('./oanda.conf').read().split(',')"
      ],
      "outputs": [],
      "execution_count": 8,
      "metadata": {
        "collapsed": true
      }
    },
    {
      "cell_type": "code",
      "source": [
        "import oandapy\n",
        "oanda = oandapy.API(environment=\"practice\", access_token=api_token)"
      ],
      "outputs": [],
      "execution_count": 9,
      "metadata": {
        "collapsed": true
      }
    },
    {
      "cell_type": "code",
      "source": [
        "data = oanda.get_history(instrument=\"EUR_USD\", \n",
        "                         granularity='D', \n",
        "                         start='2017-01-01')\n",
        "\n",
        "# convert candles to dataframe\n",
        "df = pd.DataFrame(data['candles'])\n",
        "\n",
        "df.set_index('time', inplace=True)\n",
        "df.index = pd.to_datetime(df.index)\n",
        "\ndf.tail()"
      ],
      "outputs": [
        {
          "output_type": "execute_result",
          "execution_count": 10,
          "data": {
            "text/html": [
              "<div>\n",
              "<style>\n",
              "    .dataframe thead tr:only-child th {\n",
              "        text-align: right;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: left;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>closeAsk</th>\n",
              "      <th>closeBid</th>\n",
              "      <th>complete</th>\n",
              "      <th>highAsk</th>\n",
              "      <th>highBid</th>\n",
              "      <th>lowAsk</th>\n",
              "      <th>lowBid</th>\n",
              "      <th>openAsk</th>\n",
              "      <th>openBid</th>\n",
              "      <th>volume</th>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>time</th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>2017-08-17 21:00:00</th>\n",
              "      <td>1.17633</td>\n",
              "      <td>1.17581</td>\n",
              "      <td>True</td>\n",
              "      <td>1.17758</td>\n",
              "      <td>1.17741</td>\n",
              "      <td>1.17095</td>\n",
              "      <td>1.17079</td>\n",
              "      <td>1.17235</td>\n",
              "      <td>1.17203</td>\n",
              "      <td>58908</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2017-08-20 21:00:00</th>\n",
              "      <td>1.18157</td>\n",
              "      <td>1.18135</td>\n",
              "      <td>True</td>\n",
              "      <td>1.18286</td>\n",
              "      <td>1.18273</td>\n",
              "      <td>1.17325</td>\n",
              "      <td>1.17313</td>\n",
              "      <td>1.17600</td>\n",
              "      <td>1.17500</td>\n",
              "      <td>32658</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2017-08-21 21:00:00</th>\n",
              "      <td>1.17627</td>\n",
              "      <td>1.17603</td>\n",
              "      <td>True</td>\n",
              "      <td>1.18251</td>\n",
              "      <td>1.18237</td>\n",
              "      <td>1.17461</td>\n",
              "      <td>1.17447</td>\n",
              "      <td>1.18175</td>\n",
              "      <td>1.18139</td>\n",
              "      <td>36071</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2017-08-22 21:00:00</th>\n",
              "      <td>1.18082</td>\n",
              "      <td>1.18060</td>\n",
              "      <td>True</td>\n",
              "      <td>1.18239</td>\n",
              "      <td>1.18226</td>\n",
              "      <td>1.17412</td>\n",
              "      <td>1.17393</td>\n",
              "      <td>1.17627</td>\n",
              "      <td>1.17599</td>\n",
              "      <td>39235</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2017-08-23 21:00:00</th>\n",
              "      <td>1.18063</td>\n",
              "      <td>1.18050</td>\n",
              "      <td>False</td>\n",
              "      <td>1.18190</td>\n",
              "      <td>1.18175</td>\n",
              "      <td>1.17849</td>\n",
              "      <td>1.17836</td>\n",
              "      <td>1.18105</td>\n",
              "      <td>1.18072</td>\n",
              "      <td>27493</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ],
            "text/plain": [
              "                     closeAsk  closeBid  complete  highAsk  highBid   lowAsk   lowBid  openAsk  openBid  volume\n",
              "time                                                                                                           \n",
              "2017-08-17 21:00:00   1.17633   1.17581      True  1.17758  1.17741  1.17095  1.17079  1.17235  1.17203   58908\n",
              "2017-08-20 21:00:00   1.18157   1.18135      True  1.18286  1.18273  1.17325  1.17313  1.17600  1.17500   32658\n",
              "2017-08-21 21:00:00   1.17627   1.17603      True  1.18251  1.18237  1.17461  1.17447  1.18175  1.18139   36071\n",
              "2017-08-22 21:00:00   1.18082   1.18060      True  1.18239  1.18226  1.17412  1.17393  1.17627  1.17599   39235\n",
              "2017-08-23 21:00:00   1.18063   1.18050     False  1.18190  1.18175  1.17849  1.17836  1.18105  1.18072   27493"
            ]
          },
          "metadata": {}
        }
      ],
      "execution_count": 10,
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Getting Snapshot Data\n",
        "\n",
        "- Get price of EUR/USD every 5 seconds\n",
        "- Stop after 5 ticks (for demo porposes)"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "reqs = 0\n",
        "while True:\n",
        "    price = oanda.get_prices(instruments=\"EUR_USD\")\n",
        "    print(price) # price available via price['prices'][0]\n",
        "\n",
        "    reqs += 1\n",
        "    if (reqs == 5):\n",
        "        break\n",
        "    time.sleep(1)"
      ],
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "{'prices': [{'instrument': 'EUR_USD', 'time': '2017-08-24T15:46:16.172298Z', 'bid': 1.18053, 'ask': 1.18065}]}\n",
            "{'prices': [{'instrument': 'EUR_USD', 'time': '2017-08-24T15:46:16.172298Z', 'bid': 1.18053, 'ask': 1.18065}]}\n",
            "{'prices': [{'instrument': 'EUR_USD', 'time': '2017-08-24T15:46:16.172298Z', 'bid': 1.18053, 'ask': 1.18065}]}\n",
            "{'prices': [{'instrument': 'EUR_USD', 'time': '2017-08-24T15:46:16.172298Z', 'bid': 1.18053, 'ask': 1.18065}]}\n",
            "{'prices': [{'instrument': 'EUR_USD', 'time': '2017-08-24T15:46:24.734534Z', 'bid': 1.18049, 'ask': 1.18061}]}\n"
          ]
        }
      ],
      "execution_count": 13,
      "metadata": {}
    },
    {
      "cell_type": "markdown",
      "source": [
        "---"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "skip"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Downloading Data from Interactive Brokers"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "slide"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Downloading Historical Data from Interactive Brokers\n",
        "\n",
        "Before anything...\n",
        "\n",
        "- Requires IB's TWS or IB Gateway running on your machine with API permissions enabled\n",
        "- For order execution, you also need to check \"**Bypass Order Precautions for API Orders**\" under \"Precautions\"\n",
        "- All IB examples will be using the [ezIBpy](https://github.com/ranaroussi/ezibpy) library\n",
        "\n",
        "<br><nowrap><img style=\"max-width:42%; margin:0; float:left\" src=\"http://qtpylib.io/docs/latest/_images/tws1.jpg\">\n",
        "<img style=\"max-width:54.8%; margin:0; float:left\" src=\"http://qtpylib.io/docs/latest/_images/tws2.jpg\"></nowrap>"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Interactive Brokers Example\n",
        "\n",
        "1. Connect to TWS\n",
        "- Create a callback method\n",
        "- Create a \"contract\"\n",
        "- Request historical data\n",
        "- Access historical data"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "import ezibpy\n",
        "import time\n",
        "\n",
        "# initialize ezIBpy\n",
        "ibConn = ezibpy.ezIBpy()"
      ],
      "outputs": [],
      "execution_count": 14,
      "metadata": {
        "collapsed": true
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# create callback method\n",
        "\n",
        "completed = False\n",
        "\n",
        "def ibCallback(caller, msg, **kwargs):\n",
        "    global completed\n",
        "    if caller == \"handleHistoricalData\":\n",
        "        completed = kwargs['completed']"
      ],
      "outputs": [],
      "execution_count": 15,
      "metadata": {
        "collapsed": true,
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# connect to TWS\n",
        "ibConn.connect(port=4001)\n",
        "ibConn.ibCallback = ibCallback\n",
        "\n",
        "# create a contract\n",
        "contract = ibConn.createStockContract(\"AAPL\")\n",
        "\n",
        "# request historical data\n",
        "ibConn.requestHistoricalData(resolution=\"1 day\", lookback=\"1 Y\")\n",
        "\n",
        "# wait until data is downloaded\n",
        "while not completed:\n",
        "    time.sleep(1)\n",
        "\n",
        "# if we got here, download is completed\n",
        "print(\"download completed\")\n",
        "\n",
        "# cancel request and disconnect from TWS\n",
        "ibConn.cancelHistoricalData(contract)\n",
        "ibConn.disconnect()"
      ],
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Server Version: 76\n",
            "TWS Time at connection:20170824 18:48:42 IST\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            ".........\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "download completed\n"
          ]
        }
      ],
      "execution_count": 28,
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# access historica data\n",
        "df = ibConn.historicalData['AAPL']\n",
        "df.tail()"
      ],
      "outputs": [
        {
          "output_type": "execute_result",
          "execution_count": 18,
          "data": {
            "text/html": [
              "<div>\n",
              "<style>\n",
              "    .dataframe thead tr:only-child th {\n",
              "        text-align: right;\n",
              "    }\n",
              "\n",
              "    .dataframe thead th {\n",
              "        text-align: left;\n",
              "    }\n",
              "\n",
              "    .dataframe tbody tr th {\n",
              "        vertical-align: top;\n",
              "    }\n",
              "</style>\n",
              "<table border=\"1\" class=\"dataframe\">\n",
              "  <thead>\n",
              "    <tr style=\"text-align: right;\">\n",
              "      <th></th>\n",
              "      <th>C</th>\n",
              "      <th>H</th>\n",
              "      <th>L</th>\n",
              "      <th>O</th>\n",
              "      <th>OI</th>\n",
              "      <th>V</th>\n",
              "      <th>WAP</th>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>datetime</th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "      <th></th>\n",
              "    </tr>\n",
              "  </thead>\n",
              "  <tbody>\n",
              "    <tr>\n",
              "      <th>2017-08-20</th>\n",
              "      <td>154.89</td>\n",
              "      <td>162.13</td>\n",
              "      <td>152.69</td>\n",
              "      <td>158.73</td>\n",
              "      <td>152116</td>\n",
              "      <td>180035</td>\n",
              "      <td>157.1500</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2017-08-21</th>\n",
              "      <td>156.09</td>\n",
              "      <td>161.01</td>\n",
              "      <td>151.88</td>\n",
              "      <td>154.80</td>\n",
              "      <td>152570</td>\n",
              "      <td>181123</td>\n",
              "      <td>155.0460</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2017-08-22</th>\n",
              "      <td>157.77</td>\n",
              "      <td>162.28</td>\n",
              "      <td>153.72</td>\n",
              "      <td>156.13</td>\n",
              "      <td>152129</td>\n",
              "      <td>180130</td>\n",
              "      <td>158.0560</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2017-08-23</th>\n",
              "      <td>156.50</td>\n",
              "      <td>163.15</td>\n",
              "      <td>153.84</td>\n",
              "      <td>157.73</td>\n",
              "      <td>152233</td>\n",
              "      <td>180199</td>\n",
              "      <td>157.1290</td>\n",
              "    </tr>\n",
              "    <tr>\n",
              "      <th>2017-08-24</th>\n",
              "      <td>156.99</td>\n",
              "      <td>161.44</td>\n",
              "      <td>154.08</td>\n",
              "      <td>156.58</td>\n",
              "      <td>74676</td>\n",
              "      <td>88752</td>\n",
              "      <td>156.8995</td>\n",
              "    </tr>\n",
              "  </tbody>\n",
              "</table>\n",
              "</div>"
            ],
            "text/plain": [
              "                 C       H       L       O      OI       V       WAP\n",
              "datetime                                                            \n",
              "2017-08-20  154.89  162.13  152.69  158.73  152116  180035  157.1500\n",
              "2017-08-21  156.09  161.01  151.88  154.80  152570  181123  155.0460\n",
              "2017-08-22  157.77  162.28  153.72  156.13  152129  180130  158.0560\n",
              "2017-08-23  156.50  163.15  153.84  157.73  152233  180199  157.1290\n",
              "2017-08-24  156.99  161.44  154.08  156.58   74676   88752  156.8995"
            ]
          },
          "metadata": {}
        }
      ],
      "execution_count": 18,
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "---"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "skip"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Working with Live, Streaming Data"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "slide"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Oanda Streaming Data"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "slide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "import logging\n",
        "logger = logging.getLogger()\n",
        "logger.setLevel(logging.WARNING)"
      ],
      "outputs": [],
      "execution_count": 22,
      "metadata": {
        "collapsed": true,
        "slideshow": {
          "slide_type": "skip"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Oanda Streamer"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# create streamer\n",
        "class OandaBasicStreamer(oandapy.Streamer):\n",
        "    \n",
        "    def __init__(self, *args, **kwargs):\n",
        "        oandapy.Streamer.__init__(self, *args, **kwargs)\n",
        "        self.ticks = 0\n",
        "\n",
        "    def stream(self, account_id, symbols):\n",
        "        oandapy.Streamer.start(self, \n",
        "                               accountId=account_id,\n",
        "                               instruments=symbols\n",
        "                              )\n",
        "        \n",
        "    def on_error(self, data):\n",
        "        self.disconnect()\n",
        "    \n",
        "    # logic goes here:\n",
        "    def on_success(self, data):\n",
        "        if 'tick' in data:\n",
        "            self.ticks += 1\n",
        "            print(data)"
      ],
      "outputs": [],
      "execution_count": 19,
      "metadata": {
        "collapsed": true
      }
    },
    {
      "cell_type": "code",
      "source": [
        "stream = OandaBasicStreamer(environment=\"practice\", access_token=api_token)\n",
        "\n",
        "try:\n",
        "    stream.rates(account_id, instruments=\"EUR_USD\")\n",
        "except (KeyboardInterrupt, SystemExit):\n",
        "    print('Stopped by user...')"
      ],
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "{'tick': {'instrument': 'EUR_USD', 'time': '2017-08-24T15:47:54.821310Z', 'bid': 1.18048, 'ask': 1.1806}}\n",
            "{'tick': {'instrument': 'EUR_USD', 'time': '2017-08-24T15:47:58.643527Z', 'bid': 1.18043, 'ask': 1.18056}}\n",
            "{'tick': {'instrument': 'EUR_USD', 'time': '2017-08-24T15:48:01.889783Z', 'bid': 1.18039, 'ask': 1.18052}}\n",
            "{'tick': {'instrument': 'EUR_USD', 'time': '2017-08-24T15:48:01.922014Z', 'bid': 1.18039, 'ask': 1.18051}}\n",
            "{'tick': {'instrument': 'EUR_USD', 'time': '2017-08-24T15:48:03.111637Z', 'bid': 1.18042, 'ask': 1.18054}}\n",
            "Stopped by user...\n"
          ]
        }
      ],
      "execution_count": 23,
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Plotting Oanda's Streaming Data"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "import plotly.plotly as ply\n",
        "import plotly.graph_objs as pgo\n",
        "\n",
        "import plotly.tools as tls\n",
        "stream_ids = tls.get_credentials_file()['stream_ids']"
      ],
      "outputs": [],
      "execution_count": 29,
      "metadata": {
        "slideshow": {
          "slide_type": "-"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def init_plotly_streaming_chart(token, maxpoints=100, \n",
        "                                title=\"Untitled\", auto_open=False):\n",
        "    # create a new streaming chart\n",
        "    stream = pgo.Stream(\n",
        "        token=token,\n",
        "        maxpoints=maxpoints\n",
        "    )\n",
        "    \n",
        "    # initialize streaming chart\n",
        "    tracer = pgo.Scatter(x=[], y=[], stream=stream)\n",
        "    figure = pgo.Figure(data=pgo.Data([tracer]), \n",
        "                       layout=pgo.Layout(title=title))    \n",
        "\n    return ply.plot(figure, auto_open=auto_open)"
      ],
      "outputs": [],
      "execution_count": 34,
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "chart_url = init_plotly_streaming_chart(\n",
        "    token=stream_ids[0], \n",
        "    maxpoints=50, \n",
        "    title=\"Oanda Streaming Demo\")\n",
        "\nprint(chart_url)"
      ],
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "https://plot.ly/~ranaroussi/132\n"
          ]
        }
      ],
      "execution_count": 40,
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# create streamer\n",
        "class OandaPlotter(OandaBasicStreamer):\n",
        "    \n",
        "    # logic goes here:\n",
        "    def on_success(self, data):\n",
        "        if 'tick' in data:\n",
        "            midprice = (data['tick']['bid'] + data['tick']['ask']) / 2\n",
        "            streamer.write(dict(x=self.ticks, y=midprice))\n",
        "            self.ticks += 1"
      ],
      "outputs": [],
      "execution_count": 36,
      "metadata": {
        "collapsed": true,
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "tls.embed(chart_url)"
      ],
      "outputs": [
        {
          "output_type": "execute_result",
          "execution_count": 41,
          "data": {
            "text/html": [
              "<iframe id=\"igraph\" scrolling=\"no\" style=\"border:none;\" seamless=\"seamless\" src=\"https://plot.ly/~ranaroussi/132.embed\" height=\"525\" width=\"100%\"></iframe>"
            ],
            "text/plain": [
              "<plotly.tools.PlotlyDisplay object>"
            ]
          },
          "metadata": {}
        }
      ],
      "execution_count": 41,
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "stream = OandaPlotter(environment=\"practice\", access_token=api_token)\n",
        "\n",
        "streamer = ply.Stream(stream_ids[0])\n",
        "streamer.open()\n",
        "\n",
        "try:\n",
        "    stream.rates(account_id, instruments=\"EUR_USD\")\n",
        "except (KeyboardInterrupt, SystemExit):\n",
        "    print('Stopped by user...')\n",
        "\nstreamer.close()"
      ],
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Stopped by user...\n"
          ]
        }
      ],
      "execution_count": 42,
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "---"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "skip"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Interactive Brokers Streaming Data"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "slide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "import ezibpy\n",
        "import time\n",
        "\n",
        "# initialize ezIBpy\n",
        "ibConn = ezibpy.ezIBpy()\n",
        "\n",
        "# create callback method\n",
        "def ibCallback(caller, msg, **kwargs):\n",
        "    if \"tick\" in kwargs:\n",
        "        tick = ibConn.marketData[msg.tickerId]\n",
        "        tick['datetime'] = tick.index\n",
        "        print(tick.to_dict(orient='records')[0])\n",
        "\n",
        "# connect to TWS\n",
        "ibConn.connect(port=4001)\n",
        "ibConn.ibCallback = ibCallback"
      ],
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Server Version: 76\n",
            "TWS Time at connection:20170824 18:50:23 IST\n"
          ]
        }
      ],
      "execution_count": 43,
      "metadata": {}
    },
    {
      "cell_type": "code",
      "source": [
        "# create a contract\n",
        "contract = ibConn.createFuturesContract(\"ES\", \n",
        "                exchange=\"GLOBEX\", expiry=\"201709\")\n",
        "\n",
        "# request market data for the contract\n",
        "ibConn.requestMarketData()\n",
        "\n",
        "try:\n",
        "    while True:\n",
        "        time.sleep(1)\n",
        "\n",
        "except (KeyboardInterrupt, SystemExit):\n",
        "    print('Stopped by user...')\n",
        "\n",
        "    # cancel request and disconnect from TWS\n",
        "    ibConn.cancelMarketData(contract)\n",
        "    ibConn.disconnect()"
      ],
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "{'ask': 2424.75, 'asksize': 432, 'bid': 2424.5, 'bidsize': 410, 'last': 2424.75, 'lastsize': 2, 'volume': 805304, 'datetime': '2017-08-24 18:50:27.000000'}\n",
            "{'ask': 48.25, 'asksize': 4, 'bid': 48.23, 'bidsize': 2, 'last': 48.23, 'lastsize': 5, 'volume': 236484, 'datetime': '2017-08-24 18:50:27.000000'}\n",
            "{'ask': 2424.75, 'asksize': 432, 'bid': 2424.5, 'bidsize': 410, 'last': 2424.75, 'lastsize': 2, 'volume': 805304, 'datetime': '2017-08-24 18:50:27.000000'}\n",
            "{'ask': 48.25, 'asksize': 124, 'bid': 48.23, 'bidsize': 92, 'last': 48.23, 'lastsize': 5, 'volume': 236484, 'datetime': '2017-08-24 18:50:27.000000'}\n",
            "{'ask': 2424.75, 'asksize': 176, 'bid': 2424.5, 'bidsize': 176, 'last': 2424.75, 'lastsize': 88, 'volume': 805304, 'datetime': '2017-08-24 18:50:28.000000'}\n",
            "{'ask': 48.25, 'asksize': 124, 'bid': 48.23, 'bidsize': 92, 'last': 48.24, 'lastsize': 1, 'volume': 236484, 'datetime': '2017-08-24 18:50:30.000000'}\n",
            "Stopped by user...\n"
          ]
        }
      ],
      "execution_count": 44,
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Plotting IB's Streaming Data"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "chart_url = init_plotly_streaming_chart(\n",
        "    token=stream_ids[1], \n",
        "    maxpoints=50, \n",
        "    title=\"IB Streaming Demo\")\n",
        "\nprint(chart_url)# create streamer"
      ],
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "https://plot.ly/~ranaroussi/134\n"
          ]
        }
      ],
      "execution_count": 45,
      "metadata": {
        "slideshow": {
          "slide_type": "-"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "ticks = 0\n",
        "def ibCallback(caller, msg, **kwargs):\n",
        "    global ticks\n",
        "    if \"tick\" in kwargs:\n",
        "        tick = ibConn.marketData[msg.tickerId]\n",
        "        streamer.write(dict(x=ticks, y=tick['last'].values[0]))\n",
        "        ticks += 1"
      ],
      "outputs": [],
      "execution_count": 46,
      "metadata": {
        "collapsed": true
      }
    },
    {
      "cell_type": "code",
      "source": [
        "tls.embed(chart_url)"
      ],
      "outputs": [
        {
          "output_type": "execute_result",
          "execution_count": 47,
          "data": {
            "text/html": [
              "<iframe id=\"igraph\" scrolling=\"no\" style=\"border:none;\" seamless=\"seamless\" src=\"https://plot.ly/~ranaroussi/134.embed\" height=\"525\" width=\"100%\"></iframe>"
            ],
            "text/plain": [
              "<plotly.tools.PlotlyDisplay object>"
            ]
          },
          "metadata": {}
        }
      ],
      "execution_count": 47,
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "streamer = ply.Stream(stream_ids[1])\n",
        "streamer.open()\n",
        "\n",
        "ibConn.connect(port=4001)\n",
        "ibConn.ibCallback = ibCallback\n",
        "\n",
        "contract = ibConn.createFuturesContract(\"ES\", \n",
        "                exchange=\"GLOBEX\", expiry=\"201709\")\n",
        "\n",
        "ibConn.requestMarketData()\n",
        "\n",
        "try:\n",
        "    while True:\n",
        "        time.sleep(1)\n",
        "\n",
        "except (KeyboardInterrupt, SystemExit):\n",
        "    print('Stopped by user...')\n",
        "\n",
        "    # cancel request and disconnect from TWS\n",
        "    ibConn.cancelMarketData(contract)\n",
        "    ibConn.disconnect()\n",
        "    \n",
        "    streamer.close()"
      ],
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Server Version: 76\n",
            "TWS Time at connection:20170824 18:50:47 IST\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Stopped by user...\n"
          ]
        }
      ],
      "execution_count": 48,
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "---"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "skip"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Executing & Monitoring Orders"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "slide"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Executing Orders on Oanda"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "slide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# market order\n",
        "order = oanda.create_order(account_id, \n",
        "                           instrument=\"EUR_USD\",\n",
        "                           units=1000,\n",
        "                           side='buy',\n",
        "                           type='market'\n",
        "                          )\n",
        "\npretty_print(order)"
      ],
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "{'instrument': 'EUR_USD',\n",
            " 'price': 1.18048,\n",
            " 'time': '2017-08-24T15:51:21.000000Z',\n",
            " 'tradeOpened': {'id': 10810337186,\n",
            "                 'side': 'buy',\n",
            "                 'stopLoss': 0,\n",
            "                 'takeProfit': 0,\n",
            "                 'trailingStop': 0,\n",
            "                 'units': 1000},\n",
            " 'tradeReduced': {},\n",
            " 'tradesClosed': []}\n"
          ]
        }
      ],
      "execution_count": 49,
      "metadata": {}
    },
    {
      "cell_type": "code",
      "source": [
        "# limit order\n",
        "trade_expire = datetime.datetime.now() + datetime.timedelta(hours=1)\n",
        "\n",
        "order = oanda.create_order(account_id, \n",
        "                           instrument=\"EUR_USD\",\n",
        "                           units=1000,\n",
        "                           side='buy',\n",
        "                           type='limit',\n",
        "                           price=1.1,\n",
        "                           expiry = trade_expire.isoformat(\"T\")\n",
        "                          )\n",
        "\npretty_print(order)"
      ],
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "{'instrument': 'EUR_USD',\n",
            " 'orderOpened': {'expiry': '2017-08-24T19:51:35.000000Z',\n",
            "                 'id': 10810337470,\n",
            "                 'lowerBound': 0,\n",
            "                 'side': 'buy',\n",
            "                 'stopLoss': 0,\n",
            "                 'takeProfit': 0,\n",
            "                 'trailingStop': 0,\n",
            "                 'units': 1000,\n",
            "                 'upperBound': 0},\n",
            " 'price': 1.1,\n",
            " 'time': '2017-08-24T15:51:35.000000Z'}\n"
          ]
        }
      ],
      "execution_count": 50,
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# get trade, positions, orders information\n",
        "positions = oanda.get_positions(account_id)\n",
        "trades = oanda.get_trades(account_id)\n",
        "orders = oanda.get_orders(account_id)\n",
        "\npositions, trades, orders"
      ],
      "outputs": [
        {
          "output_type": "execute_result",
          "execution_count": 51,
          "data": {
            "text/plain": [
              "({'positions': [{'avgPrice': 1.18048,\n",
              "    'instrument': 'EUR_USD',\n",
              "    'side': 'buy',\n",
              "    'units': 1000}]},\n",
              " {'trades': [{'id': 10810337186,\n",
              "    'instrument': 'EUR_USD',\n",
              "    'price': 1.18048,\n",
              "    'side': 'buy',\n",
              "    'stopLoss': 0,\n",
              "    'takeProfit': 0,\n",
              "    'time': '2017-08-24T15:51:21.000000Z',\n",
              "    'trailingAmount': 0,\n",
              "    'trailingStop': 0,\n",
              "    'units': 1000}]},\n",
              " {'orders': [{'expiry': '2017-08-24T19:51:35.000000Z',\n",
              "    'id': 10810337470,\n",
              "    'instrument': 'EUR_USD',\n",
              "    'lowerBound': 0,\n",
              "    'price': 1.1,\n",
              "    'side': 'buy',\n",
              "    'stopLoss': 0,\n",
              "    'takeProfit': 0,\n",
              "    'time': '2017-08-24T15:51:35.000000Z',\n",
              "    'trailingStop': 0,\n",
              "    'type': 'limit',\n",
              "    'units': 1000,\n",
              "    'upperBound': 0}]})"
            ]
          },
          "metadata": {}
        }
      ],
      "execution_count": 51,
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# close posiiton (market)\n",
        "order = oanda.create_order(account_id, \n",
        "                           instrument=\"EUR_USD\",\n",
        "                           units=1000,\n",
        "                           type='market',\n",
        "                           side='sell'\n",
        "                          )\n",
        "\npretty_print(order)"
      ],
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "{'instrument': 'EUR_USD',\n",
            " 'price': 1.18031,\n",
            " 'time': '2017-08-24T15:51:40.000000Z',\n",
            " 'tradeOpened': {},\n",
            " 'tradeReduced': {},\n",
            " 'tradesClosed': [{'id': 10810337186, 'side': 'buy', 'units': 1000}]}\n"
          ]
        }
      ],
      "execution_count": 52,
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# get trade, positions, orders information\n",
        "positions = oanda.get_positions(account_id)\n",
        "trades = oanda.get_trades(account_id)\n",
        "orders = oanda.get_orders(account_id)\n",
        "\npositions, trades, orders"
      ],
      "outputs": [
        {
          "output_type": "execute_result",
          "execution_count": 53,
          "data": {
            "text/plain": [
              "({'positions': []},\n",
              " {'trades': []},\n",
              " {'orders': [{'expiry': '2017-08-24T19:51:35.000000Z',\n",
              "    'id': 10810337470,\n",
              "    'instrument': 'EUR_USD',\n",
              "    'lowerBound': 0,\n",
              "    'price': 1.1,\n",
              "    'side': 'buy',\n",
              "    'stopLoss': 0,\n",
              "    'takeProfit': 0,\n",
              "    'time': '2017-08-24T15:51:35.000000Z',\n",
              "    'trailingStop': 0,\n",
              "    'type': 'limit',\n",
              "    'units': 1000,\n",
              "    'upperBound': 0}]})"
            ]
          },
          "metadata": {}
        }
      ],
      "execution_count": 53,
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# close pending order\n",
        "orderId = orders['orders'][0]['id']\n",
        "oanda.close_order(account_id, orderId)\n",
        "\npretty_print(order)"
      ],
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "{'instrument': 'EUR_USD',\n",
            " 'price': 1.18031,\n",
            " 'time': '2017-08-24T15:51:40.000000Z',\n",
            " 'tradeOpened': {},\n",
            " 'tradeReduced': {},\n",
            " 'tradesClosed': [{'id': 10810337186, 'side': 'buy', 'units': 1000}]}\n"
          ]
        }
      ],
      "execution_count": 54,
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# get trade, positions, orders information\n",
        "positions = oanda.get_positions(account_id)\n",
        "trades = oanda.get_trades(account_id)\n",
        "orders = oanda.get_orders(account_id)\n",
        "\npositions, trades, orders"
      ],
      "outputs": [
        {
          "output_type": "execute_result",
          "execution_count": 55,
          "data": {
            "text/plain": [
              "({'positions': []}, {'trades': []}, {'orders': []})"
            ]
          },
          "metadata": {}
        }
      ],
      "execution_count": 55,
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "---"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "skip"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Executing Orders on Interactive Brokers"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "slide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "import ezibpy\n",
        "\n",
        "# initialize ezIBpy\n",
        "ibConn = ezibpy.ezIBpy()\n",
        "\n",
        "# create callback method\n",
        "def ibCallback(caller, msg, **kwargs):\n",
        "    if caller == \"handleOrders\":\n",
        "        order = ibConn.orders[msg.orderId]\n",
        "        print('Order > ', order)"
      ],
      "outputs": [],
      "execution_count": 56,
      "metadata": {}
    },
    {
      "cell_type": "code",
      "source": [
        "# issue market order\n",
        "ibConn.connect(port=4001)\n",
        "ibConn.ibCallback = ibCallback\n",
        "\n",
        "contract = ibConn.createFuturesContract(\"ES\", \n",
        "                exchange=\"GLOBEX\", expiry=\"201709\")\n",
        "\n",
        "order = ibConn.createOrder(1)\n",
        "orderId = ibConn.placeOrder(contract, order)\n",
        "time.sleep(1)\n",
        "\nibConn.disconnect()"
      ],
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Server Version: 76\n",
            "TWS Time at connection:20170824 18:51:52 IST\n",
            "Order >  {'id': 196, 'symbol': 'ESU2017_FUT', 'order': <ib.ext.Order.Order object at 0x11eb65d68>, 'status': 'OPENED', 'reason': None, 'avgFillPrice': 0.0, 'parentId': 0, 'time': datetime.datetime(2017, 8, 24, 18, 51, 52)}\n",
            "Order >  {'id': 196, 'symbol': 'ESU2017_FUT', 'order': <ib.ext.Order.Order object at 0x11eb65d68>, 'status': 'SUBMITTED', 'reason': None, 'avgFillPrice': 0.0, 'parentId': 0, 'time': datetime.datetime(2017, 8, 24, 18, 51, 52)}\n",
            "Order >  {'id': 196, 'symbol': 'ESU2017_FUT', 'order': <ib.ext.Order.Order object at 0x11eb65d68>, 'status': 'FILLED', 'reason': None, 'avgFillPrice': 2424.75, 'parentId': 0, 'time': datetime.datetime(2017, 8, 24, 18, 51, 53)}\n"
          ]
        }
      ],
      "execution_count": 57,
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# get trade, positions, orders information\n",
        "ibConn.positions, ibConn.portfolio, ibConn.orders"
      ],
      "outputs": [
        {
          "output_type": "execute_result",
          "execution_count": 58,
          "data": {
            "text/plain": [
              "({'CLU2017_FUT': {'account': 'DU15012',\n",
              "   'avgCost': 0.0,\n",
              "   'position': 0,\n",
              "   'symbol': 'CLU2017_FUT'},\n",
              "  'ESU2017_FUT': {'account': 'DU15012',\n",
              "   'avgCost': 121237.5,\n",
              "   'position': 1,\n",
              "   'symbol': 'ESU2017_FUT'}},\n",
              " {'CLU2017_FUT': {'account': 'DU15012',\n",
              "   'averageCost': 0.0,\n",
              "   'marketPrice': 48.2200012,\n",
              "   'marketValue': 0.0,\n",
              "   'position': 0,\n",
              "   'realizedPNL': -540.0,\n",
              "   'symbol': 'CLU2017_FUT',\n",
              "   'totalPNL': -540.0,\n",
              "   'unrealizedPNL': 0.0},\n",
              "  'ESU2017_FUT': {'account': 'DU15012',\n",
              "   'averageCost': 0.0,\n",
              "   'marketPrice': 2424.625,\n",
              "   'marketValue': 0.0,\n",
              "   'position': 0,\n",
              "   'realizedPNL': -2595.9,\n",
              "   'symbol': 'ESU2017_FUT',\n",
              "   'totalPNL': -2595.9,\n",
              "   'unrealizedPNL': 0.0}},\n",
              " {196: {'avgFillPrice': 2424.75,\n",
              "   'id': 196,\n",
              "   'order': <ib.ext.Order.Order at 0x11eb65d68>,\n",
              "   'parentId': 0,\n",
              "   'reason': None,\n",
              "   'status': 'FILLED',\n",
              "   'symbol': 'ESU2017_FUT',\n",
              "   'time': datetime.datetime(2017, 8, 24, 18, 51, 53)}})"
            ]
          },
          "metadata": {}
        }
      ],
      "execution_count": 58,
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# bracker limit order\n",
        "ibConn.connect(port=4001)\n",
        "ibConn.ibCallback = ibCallback\n",
        "\n",
        "contract = ibConn.createFuturesContract(\"ES\", \n",
        "                exchange=\"GLOBEX\", expiry=\"201709\")\n",
        "\n",
        "order = ibConn.createBracketOrder(\n",
        "    contract, quantity=1, entry=2400, target=2500., stop=2300.)\n",
        "\n",
        "time.sleep(1)\n",
        "ibConn.disconnect()"
      ],
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Server Version: 76\n",
            "TWS Time at connection:20170824 18:52:04 IST\n",
            "Order >  {'id': 198, 'symbol': 'ESU2017_FUT', 'order': <ib.ext.Order.Order object at 0x11eefecc0>, 'status': 'OPENED', 'reason': None, 'avgFillPrice': 0.0, 'parentId': 0, 'time': datetime.datetime(2017, 8, 24, 18, 52, 4)}\n",
            "Order >  {'id': 198, 'symbol': 'ESU2017_FUT', 'order': <ib.ext.Order.Order object at 0x11eefecc0>, 'status': 'PRESUBMITTED', 'reason': 'child,locate', 'avgFillPrice': 0.0, 'parentId': 197, 'time': datetime.datetime(2017, 8, 24, 18, 52, 4)}\n",
            "Order >  {'id': 201, 'symbol': 'ESU2017_FUT', 'order': <ib.ext.Order.Order object at 0x11ef06c18>, 'status': 'OPENED', 'reason': None, 'avgFillPrice': 0.0, 'parentId': 0, 'time': datetime.datetime(2017, 8, 24, 18, 52, 5)}\n",
            "Order >  {'id': 201, 'symbol': 'ESU2017_FUT', 'order': <ib.ext.Order.Order object at 0x11ef06c18>, 'status': 'PRESUBMITTED', 'reason': 'child,locate,trigger', 'avgFillPrice': 0.0, 'parentId': 197, 'time': datetime.datetime(2017, 8, 24, 18, 52, 5)}\n",
            "Order >  {'id': 197, 'symbol': 'ESU2017_FUT', 'order': <ib.ext.Order.Order object at 0x11eeee9e8>, 'status': 'OPENED', 'reason': None, 'avgFillPrice': 0.0, 'parentId': 0, 'time': datetime.datetime(2017, 8, 24, 18, 52, 5)}\n",
            "Order >  {'id': 197, 'symbol': 'ESU2017_FUT', 'order': <ib.ext.Order.Order object at 0x11eeee9e8>, 'status': 'SUBMITTED', 'reason': None, 'avgFillPrice': 0.0, 'parentId': 0, 'time': datetime.datetime(2017, 8, 24, 18, 52, 5)}\n"
          ]
        }
      ],
      "execution_count": 59,
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# get order information\n",
        "pretty_print(ibConn.orders)"
      ],
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "{196: {'avgFillPrice': 2424.75,\n",
            "       'id': 196,\n",
            "       'order': <ib.ext.Order.Order object at 0x11eb65d68>,\n",
            "       'parentId': 0,\n",
            "       'reason': None,\n",
            "       'status': 'FILLED',\n",
            "       'symbol': 'ESU2017_FUT',\n",
            "       'time': datetime.datetime(2017, 8, 24, 18, 51, 53)},\n",
            " 197: {'avgFillPrice': 0.0,\n",
            "       'id': 197,\n",
            "       'order': <ib.ext.Order.Order object at 0x11eeee9e8>,\n",
            "       'parentId': 0,\n",
            "       'reason': None,\n",
            "       'status': 'SUBMITTED',\n",
            "       'symbol': 'ESU2017_FUT',\n",
            "       'time': datetime.datetime(2017, 8, 24, 18, 52, 5)},\n",
            " 198: {'avgFillPrice': 0.0,\n",
            "       'id': 198,\n",
            "       'order': <ib.ext.Order.Order object at 0x11eefecc0>,\n",
            "       'parentId': 197,\n",
            "       'reason': 'child,locate',\n",
            "       'status': 'PRESUBMITTED',\n",
            "       'symbol': 'ESU2017_FUT',\n",
            "       'time': datetime.datetime(2017, 8, 24, 18, 52, 4)},\n",
            " 201: {'avgFillPrice': 0.0,\n",
            "       'id': 201,\n",
            "       'order': <ib.ext.Order.Order object at 0x11ef06c18>,\n",
            "       'parentId': 197,\n",
            "       'reason': 'child,locate,trigger',\n",
            "       'status': 'PRESUBMITTED',\n",
            "       'symbol': 'ESU2017_FUT',\n",
            "       'time': datetime.datetime(2017, 8, 24, 18, 52, 5)}}\n"
          ]
        }
      ],
      "execution_count": 60,
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "---"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "skip"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Live Trading Example"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "slide"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "## Live Trading \"Template\"\n",
        "\n",
        "- Subscribe to streaming data (resample data if necessary)\n",
        "- Run strategy logic\n",
        "- Execute & monitor orders"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "# build ohlc _bars\n",
        "_bars = pd.DataFrame()\n",
        "_ticks = pd.DataFrame()\n",
        "_res = '1T'\n",
        "_window = 100\n",
        "\n",
        "def ibCallback(caller, msg, **kwargs):\n",
        "    global _bars, _ticks, _res, _window\n",
        "    \n",
        "    if caller == \"handleOrders\":\n",
        "        order = ibConn.orders[msg.orderId]\n",
        "        print('Order > ', order)\n",
        "        \n",
        "    elif \"tick\" in kwargs:\n",
        "        # read tick\n",
        "        tick = ibConn.marketData[msg.tickerId]\n",
        "        \n",
        "        # add to _ticks df\n",
        "        _ticks = pd.concat([_ticks, tick])\n",
        "        _ticks.index = pd.to_datetime(_ticks.index)\n",
        "\n",
        "        # on_new_bar(_ticks.copy())\n",
        "        # return \n",
        "\n",
        "        # resample _ticks to 1min _bars\n",
        "        ticks_as_bars = _ticks['last'].resample(_res).ohlc()\n",
        "        ticks_as_bars['volume'] = _ticks['lastsize'].resample(_res).sum()\n",
        "\n",
        "        # replace latest bar data with resampled _ticks\n",
        "        _bars = _bars[_bars.index != ticks_as_bars.index[-1]]        \n",
        "        _bars = pd.concat([_bars, ticks_as_bars[-1:]])\n",
        "        \n",
        "        # remove old _ticks\n",
        "        pre_trimmed_ticks = len(_ticks)\n",
        "        _ticks = _ticks[_ticks.index >= ticks_as_bars.index[-1]]\n",
        "\n",
        "        # run strategy logic\n",
        "        if len(_ticks) != pre_trimmed_ticks:\n",
        "            on_new_bar(_bars[-_window:].copy())"
      ],
      "outputs": [],
      "execution_count": 61,
      "metadata": {
        "scrolled": false,
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "def on_new_bar(bars):\n",
        "\n",
        "    position = 0\n",
        "    if contractString in ibConn.positions:\n",
        "        position = ibConn.positions[contractString]['position']\n",
        "        \n",
        "    # calculate sma\n",
        "    bars['sma'] = bars['close'].rolling(2).mean()\n",
        "\n",
        "    # get lastest bar as dict\n",
        "    bar = bars.to_dict(orient='records')[-1]\n",
        "    \n",
        "    order_qty = 0\n",
        "    \n",
        "    if bar['close'] > bar['sma'] and position <= 0:\n",
        "        order_qty = abs(position) + 1\n",
        "\n",
        "    elif bar['close'] < bar['sma'] and position >= 0:\n",
        "        order_qty = -abs(position) - order_qty\n",
        "\n",
        "    # send order?\n",
        "    if order_qty != 0:\n",
        "        print('order qty ==>', order_qty)\n",
        "        order = ibConn.createOrder(order_qty)\n",
        "        ibConn.placeOrder(contract, order)"
      ],
      "outputs": [],
      "execution_count": 62,
      "metadata": {
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "code",
      "source": [
        "ibConn.connect(port=4001)\n",
        "ibConn.ibCallback = ibCallback\n",
        "\n",
        "contract = ibConn.createFuturesContract(\"ES\", \n",
        "                exchange=\"GLOBEX\", expiry=\"201709\")\n",
        "\n",
        "contractString = ibConn.contractString(contract)\n",
        "\n",
        "ibConn.requestMarketData()\n",
        "\n",
        "try:\n",
        "    while True:\n",
        "        time.sleep(1)\n",
        "\n",
        "except (KeyboardInterrupt, SystemExit):\n",
        "    print('Stopped by user...')\n",
        "\n",
        "    # cancel request and disconnect from TWS\n",
        "    ibConn.cancelMarketData(contract)\n",
        "    ibConn.disconnect()"
      ],
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Server Version: 76\n",
            "TWS Time at connection:20170824 18:52:40 IST\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "order qty ==> -1\n",
            "order qty ==> -1\n",
            "Order >  {'id': 202, 'symbol': 'ESU2017_FUT', 'order': <ib.ext.Order.Order object at 0x11ef1f160>, 'status': 'OPENED', 'reason': None, 'avgFillPrice': 0.0, 'parentId': 0, 'time': datetime.datetime(2017, 8, 24, 18, 52, 40)}\n",
            "Order >  {'id': 202, 'symbol': 'ESU2017_FUT', 'order': <ib.ext.Order.Order object at 0x11ef1f160>, 'status': 'FILLED', 'reason': None, 'avgFillPrice': 2424.75, 'parentId': 0, 'time': datetime.datetime(2017, 8, 24, 18, 52, 40)}\n",
            "Order >  {'id': 203, 'symbol': 'ESU2017_FUT', 'order': <ib.ext.Order.Order object at 0x11eb388d0>, 'status': 'OPENED', 'reason': None, 'avgFillPrice': 0.0, 'parentId': 0, 'time': datetime.datetime(2017, 8, 24, 18, 52, 42)}\n",
            "Order >  {'id': 203, 'symbol': 'ESU2017_FUT', 'order': <ib.ext.Order.Order object at 0x11eb388d0>, 'status': 'FILLED', 'reason': None, 'avgFillPrice': 2424.75, 'parentId': 0, 'time': datetime.datetime(2017, 8, 24, 18, 52, 42)}\n",
            "order qty ==> 2\n"
          ]
        },
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Order >  {'id': 204, 'symbol': 'ESU2017_FUT', 'order': <ib.ext.Order.Order object at 0x11ee6ee10>, 'status': 'OPENED', 'reason': None, 'avgFillPrice': 0.0, 'parentId': 0, 'time': datetime.datetime(2017, 8, 24, 18, 52, 42)}\n",
            "Order >  {'id': 204, 'symbol': 'ESU2017_FUT', 'order': <ib.ext.Order.Order object at 0x11ee6ee10>, 'status': 'FILLED', 'reason': None, 'avgFillPrice': 2425.0, 'parentId': 0, 'time': datetime.datetime(2017, 8, 24, 18, 52, 42)}\n",
            "order qty ==> -1\n",
            "Order >  {'id': 205, 'symbol': 'ESU2017_FUT', 'order': <ib.ext.Order.Order object at 0x11ef06630>, 'status': 'OPENED', 'reason': None, 'avgFillPrice': 0.0, 'parentId': 0, 'time': datetime.datetime(2017, 8, 24, 18, 52, 43)}\n",
            "Order >  {'id': 205, 'symbol': 'ESU2017_FUT', 'order': <ib.ext.Order.Order object at 0x11ef06630>, 'status': 'FILLED', 'reason': None, 'avgFillPrice': 2424.75, 'parentId': 0, 'time': datetime.datetime(2017, 8, 24, 18, 52, 43)}\n",
            "order qty ==> 1\n",
            "Stopped by user...\n"
          ]
        }
      ],
      "execution_count": 64,
      "metadata": {
        "scrolled": false,
        "slideshow": {
          "slide_type": "subslide"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "---"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "skip"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# To Be Continued..."
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "slide"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "This was the part 3 out of the 4-part webinar series\n",
        "\n",
        "### Up Next...\n",
        "\n",
        "- <strike>Prototyping Trading Strategies</strike>\n",
        "- <strike>Backtesting & Optimization</strike>\n",
        "- <strike>Live Trading</strike>\n",
        "- Using Machine Learning in Trading"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "fragment"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "# Q&A Time"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "slide"
        }
      }
    },
    {
      "cell_type": "markdown",
      "source": [
        "<img style=\"max-width:100px!important;border-radius:50%;margin:0\" src=\"http://aroussi.com/assets/img/ran.jpg\">\n",
        "\n",
        "# Live Algorithmic Trading with Python\n",
        "\n\n",
        "---\n",
        "\n",
        "### Thank you for attending!\n",
        "\n",
        "<br>\n",
        "\n",
        "&copy; Ran Aroussi<br>\n",
        "[@aroussi](http://twitter.com/aroussi) | [aroussi.com](http://aroussi.com) | [github.com/ranaroussi](https://github.com/ranaroussi)\n",
        "\n\n",
        "<img style=\"float:left; max-width:120px!important;margin:20px 0 0\" src=\"https://futures.io/images/logo-black.png\">\n",
        "<br clear=\"all\"><br><small>August, 2017</small>"
      ],
      "metadata": {
        "slideshow": {
          "slide_type": "slide"
        }
      }
    }
  ],
  "metadata": {
    "celltoolbar": "Slideshow",
    "kernelspec": {
      "name": "python3",
      "language": "python",
      "display_name": "Python 3"
    },
    "language_info": {
      "name": "python",
      "version": "3.6.6",
      "mimetype": "text/x-python",
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "pygments_lexer": "ipython3",
      "nbconvert_exporter": "python",
      "file_extension": ".py"
    },
    "kernel_info": {
      "name": "python3"
    },
    "nteract": {
      "version": "0.11.9"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 2
}